package com.dongrj.framework.sftp;

import com.dongrj.framework.core.utils.StringUtils;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

import java.util.Properties;


@Slf4j
public class SftpFactory extends BasePooledObjectFactory<ChannelSftp> {

    private Integer clientNum = 0;

    private SftpProperties sftpProperties;

    public SftpFactory(SftpProperties sftpProperties) {
        this.sftpProperties = sftpProperties;
    }

    @Override
    public ChannelSftp create() {
        try {
            JSch jSch = new JSch();
            if (StringUtils.isNotEmpty(sftpProperties.getPrivateKey())) {
                jSch.addIdentity(sftpProperties.getPrivateKey());
            }
            Session session = jSch.getSession(sftpProperties.getUsername(), sftpProperties.getHostname(), sftpProperties.getPort());
            StringUtils.notEmpty(sftpProperties.getPassword(), session::setPassword);
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            session.setConfig(sshConfig);
            session.setTimeout(sftpProperties.getTimeout());
            session.connect();
            Channel sftp = session.openChannel("sftp");
            sftp.connect();
            log.info("create success client:{}", ++clientNum);
            return (ChannelSftp) sftp;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("创建Sftp链接异常[{}]异常!", sftpProperties, e);
            throw new RuntimeException(String.format("创建Sftp链接异常[%s]异常!", sftpProperties), e);
        }
    }

    @Override
    public PooledObject<ChannelSftp> wrap(ChannelSftp channelSftp) {
        return new DefaultPooledObject<>(channelSftp);
    }

    @Override
    public void destroyObject(PooledObject<ChannelSftp> sftpPooledObject) throws Exception {
        if (sftpPooledObject != null) {
            ChannelSftp object = sftpPooledObject.getObject();
            SftpUtils.close(object);
        }
    }
}
